package org.btik.light.mobile.ui.devs.camcar;

import android.view.View;
import android.widget.CompoundButton;
import org.btik.light.mobile.common.handler.adaptor.ClickerAdaptor;
import org.btik.light.mobile.common.handler.adaptor.DevBinderOnCheckedChangeListener;
import org.btik.light.mobile.common.handler.nbi.NbiController;
import org.btik.light.mobile.common.handler.nbi.NbiSpeedController;
import org.btik.light.mobile.common.handler.adaptor.SpeedHandler;
import org.btik.light.mobile.common.handler.adaptor.TurnEventHandler;
import org.btik.light.mobile.common.handler.nbi.NbiVideoOnController;


/**
 * @author lustre
 * @since 2023/4/30 14:55
 */
public interface CamCarRawCommandHandlers {
    byte NBI_CMD_TYPE = 0; // raw
    byte CAR_GENERAL_OP = '1';

    byte FORWARD = '0';

    byte BACKWARD = '1';

    byte TURN_LEFT = '2';

    byte TURN_RIGHT = '3';

    byte END_TURN_LEFT = '4';

    byte END_TURN_RIGHT = '5';

    byte STOP = '6';

    byte GO_PIKACHU = '7';

    byte SPEED_OPT = '2';
    byte SET_SPEED = '0';

    byte[] MAX_SPEED = new byte[]{'1', '0', '0'};

    /**
     * 摄像头操作
     */
    byte CAM_GENERAL_OP = '3';

    byte START_SEND = '0';

    byte STOP_SEND = '1';

    byte LED_ON = '2';

    byte LED_OFF = '3';

    byte CAM_SETTING_OP = '4';

    byte SINGLE = '0';

    byte OTHER = '1';

    byte[] VERTICAL_FLIP = {'1', '1'};

    byte[] HORIZONTAL_MIRROR = {'1', '0'};

    byte STATUS_ON = '1';

    byte STATUS_OFF = '0';


    /* 前
     */
    View.OnClickListener GO_FORWARD = newClick(CAR_GENERAL_OP, FORWARD);

    /**
     * 倒车
     */
    View.OnClickListener GO_BACKWARD = newClick(CAR_GENERAL_OP, BACKWARD);

    /**
     * 左转
     */
    View.OnTouchListener TO_TURN_LEFT = new TurnEventHandler(new NbiController(create(CAR_GENERAL_OP, TURN_LEFT)),
            new NbiController(create(CAR_GENERAL_OP, END_TURN_LEFT)));
    /**
     * 右转
     */
    View.OnTouchListener TO_TURN_RIGHT = new TurnEventHandler(new NbiController(create(CAR_GENERAL_OP, TURN_RIGHT)),
            new NbiController(create(CAR_GENERAL_OP, END_TURN_RIGHT)));

    /**
     * 停车
     */
    View.OnClickListener TO_STOP = newClick(CAR_GENERAL_OP, STOP);

    SpeedHandler SPEED_HANDLER = new SpeedHandler(new NbiSpeedController(createSpeedTemplate(SPEED_OPT, SET_SPEED, MAX_SPEED)),
            new NbiController(create(CAR_GENERAL_OP, GO_PIKACHU)));

    NbiVideoOnController VIDEO_ON = new NbiVideoOnController(create(CAM_GENERAL_OP, START_SEND));

    NbiController VIDEO_0FF = new NbiController(create(CAM_GENERAL_OP, STOP_SEND));

    NbiController LIGHT_ON = new NbiController(create(CAM_GENERAL_OP, LED_ON));

    NbiController LIGHT_OFF = new NbiController(create(CAM_GENERAL_OP, LED_OFF));

    CompoundButton.OnCheckedChangeListener VIDEO_SWITCH = new DevBinderOnCheckedChangeListener(VIDEO_ON, VIDEO_0FF);

    CompoundButton.OnCheckedChangeListener LIGHT_SWITCH = new DevBinderOnCheckedChangeListener(LIGHT_ON, LIGHT_OFF);

    CompoundButton.OnCheckedChangeListener VERTICAL_FLIP_SWITCH = newSwitch(CAM_SETTING_OP, SINGLE, VERTICAL_FLIP, STATUS_ON, STATUS_OFF);

    CompoundButton.OnCheckedChangeListener HORIZONTAL_MIRROR_SWITCH = newSwitch(CAM_SETTING_OP, SINGLE, HORIZONTAL_MIRROR, STATUS_ON, STATUS_OFF);

    static byte[] create(byte op, byte arg) {
        return new byte[]{
                'L', 'N', 'B', 'I',
                NBI_CMD_TYPE,
                12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                'i', 'd', ':', '0', '\n',
                'o', 'p', ':', op, '\n',
                arg, '\n'
        };
    }

    static byte[] create(byte op, byte arg0, byte arg1) {
        return new byte[]{
                'L', 'N', 'B', 'I',
                NBI_CMD_TYPE,
                12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                'i', 'd', ':', '0', '\n',
                'o', 'p', ':', op, '\n',
                arg0, ' ', arg1, '\n'
        };
    }

    static ClickerAdaptor newClick(byte op, byte arg) {
        return new ClickerAdaptor(new NbiController(create(op, arg)));
    }

    static DevBinderOnCheckedChangeListener newSwitch(byte op, byte type, byte[] settingIndex, byte statusOn, byte statusOff) {
        return new DevBinderOnCheckedChangeListener(new NbiController(createCamSettingTemplate(op, type, settingIndex, statusOn)),
                new NbiController(createCamSettingTemplate(op, type, settingIndex, statusOff))
        );
    }

    static byte[] createSpeedTemplate(byte op, byte action, byte[] val) {
        if (val.length < 3) {
            throw new IllegalArgumentException("speed must be 3 byte char");
        }
        return new byte[]{
                'L', 'N', 'B', 'I',
                NBI_CMD_TYPE,
                12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                'i', 'd', ':', '0', '\n',
                'o', 'p', ':', op, '\n',
                action, ' ', val[0], val[1], val[2], '\n'
        };
    }

    static byte[] createCamSettingTemplate(byte op, byte type, byte[] settingIndex, byte status) {
        if (settingIndex.length < 2) {
            throw new IllegalArgumentException("speed must be 2 byte char");
        }
        return new byte[]{
                'L', 'N', 'B', 'I',
                NBI_CMD_TYPE,
                12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                'i', 'd', ':', '0', '\n',
                'o', 'p', ':', op, '\n',
                type, ' ', settingIndex[0], settingIndex[1], ' ', status, '\n'
        };
    }

    CamCarActionMeta UDP_RAW_META = new CamCarActionMeta()
            .setSpeedHandler(SPEED_HANDLER)
            .setGoBackward(GO_BACKWARD)
            .setGoForward(GO_FORWARD)
            .setToTurnLeft(TO_TURN_LEFT)
            .setToTurnRight(TO_TURN_RIGHT)
            .setToStop(TO_STOP)
            .setLightSwitch(LIGHT_SWITCH)
            .setLightOn(LIGHT_ON)
            .setVideoOff(LIGHT_OFF)
            .setVideoSwitch(VIDEO_SWITCH)
            .setVideoOn(VIDEO_ON)
            .setVideoOff(VIDEO_0FF)
            .setLightOff(LIGHT_OFF)
            .setHorizontalMirrorSwitch(HORIZONTAL_MIRROR_SWITCH)
            .setVerticalFlip(VERTICAL_FLIP_SWITCH);

}
